﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using Barbar.MapReport.Common;

namespace Barbar.MapReport.DataSource {
  [XmlTypeAttribute(TypeName="P", Namespace= Constants.DataSourceXmlNamespace)]
  public struct Point : IGeoPoint, IGeoBound {
    private decimal m_Latitude;
    private decimal m_Longitude;

    public static readonly Point Empty = new Point(0m, 0m);

    [XmlAttribute(AttributeName="lat")]
    public decimal Latitude {
      get { return m_Latitude; }
      set { m_Latitude = value; }
    }

    [XmlAttribute(AttributeName="lng")]
    public decimal Longitude {
      get { return m_Longitude; }
      set { m_Longitude = value; }
    }

    public Point(decimal latitude, decimal longitude) {
      m_Latitude = latitude;
      m_Longitude = longitude;
    }

    public Point(IGeoPoint point) {
      if (point == null)
        throw new ArgumentNullException("point");

      m_Latitude = point.Latitude;
      m_Longitude = point.Longitude;
    }

    public override bool Equals(object obj) {
      Point anotherPoint = (Point)obj;
      return AreEqual(this, anotherPoint);
    }

    public override int GetHashCode() {
      return m_Latitude.GetHashCode() ^ m_Longitude.GetHashCode();
    }

    private static bool AreEqual(Point firstPoint, Point secondPoint) {
      return firstPoint.Latitude == secondPoint.Latitude && firstPoint.Longitude == secondPoint.Longitude;
    }

    public static bool operator==(Point firstPoint, Point secondPoint) {
      return AreEqual(firstPoint, secondPoint);
    }

    public static bool operator!=(Point firstPoint, Point secondPoint) {
      return !AreEqual(firstPoint, secondPoint);
    }

    #region IGeoBound Members

    IGeoPoint IGeoBound.Northeast {
      get { return this; ; }
    }

    IGeoPoint IGeoBound.Southwest {
      get { return this; ; }
    }

    #endregion
  }
}
